文章目录
  1. 1. ORACLE 字符集长度问题

ORACLE 字符集长度问题

ORACLE 字符集长度问题

\

很多新手在做建数据库时,会这样忽略一个问题:ORACLE中VARCHAR2类型的字段长度是按照byte来定义的。如果数据库使用的字
符集是GBK,GB2312或者其他定长字符集的话,这个问题似乎可以被忽略,因为只要把数据库的字段长度/2就可以得到你要限制插入该字段的中文长度
了。 但是,如果数据库的字符集是UTF-8呢,杯具了吧,人家是变长的。

      有人说数据库字段长度/3,这是一定不可取的,因为UTF-8是变长表示的,平均为3byte表示一个字符,而并不是一定用3byte。

      其实人家ORACLE没这么笨,本来就可以用字符为单位来定义varchar2的长度的,这个时候需要注意在建表时这样写:

  

Sql代码

  

  1. create  table  ABC_TABLE  (A_FIELD  varchar2(20  char))    

     

      这个varchar2(20
char)就表示了是用字符为单位来定义了,而默认情况下的varchar2(20)这样就是字节!

      如果你之前没考虑到这个问题,而现在遇到了,又想更改你的字段定义的话,可以这样写:

  

Sql代码
  

  1. alter  table  ABC_TABLE  modify  (A_FIELD  varchar2(20  char))    

     

但是如果你不确定究竟是怎么定义的,或者,你想找出所有采用字节定义长度的字段,可以试试用这样的方法:

  

Sql代码
  

  1. select  *  from  user_tab_columns  where  CHAR_USED=‘B’    

  这里的CHAR_USED的意思是:如果是字符定义-‘C’,字节定义-‘B’

  

如果需要批量修改所有的以字节数定义的字符串长度,需要创建一个类似这样的存储过程:

  

Sql代码
  

  1. create  or  replace  procedure  pro_fix_varchar  as    
  2. cursor  fieldList  is    
  3.     select  T1.TABLE_NAME,T1.COLUMN_NAME,T1.DATA_LENGTH  from  USER_TAB_COLUMNS  T1    
  4.       left  join  user_tables  T2  on  T2.TABLE_NAME=T1.TABLE_NAME    
  5.       where  T2.TABLE_NAME  is  not  null    
  6.       and  T2.TABLESPACE_NAME=‘MY_TABLESPACE’  –请把这里修改为你自己的表空间名    
  7.       and  CHAR_USED=‘B’;    
  8. tblName  varchar2(2000);    
  9. fieldName  varchar2(2000);    
  10. dataLen  varchar2(10);    
  11. sqlStr  varchar2(2000);    
  12. cnt  integer;    
  13. BEGIN    
  14.     dbms_output.put_line(‘begin’);    
  15.     cnt:=0;    
  16.     open  fieldList;    
  17.     loop    
  18.         fetch  fieldList  into  tblName,fieldName,dataLen;    
  19.         exit  when  fieldList%notfound;    
  20.         sqlStr:=‘alter  table  “‘||tblName||‘“  modify  (“‘||fieldName||‘“  varchar2(‘||dataLen||‘  char))’;    
  21.         execute  immediate  sqlStr;    
  22.         commit;    
  23.         cnt:=cnt+1;    
  24.     end  loop;    
  25.     close  fieldList;    
  26.     dbms_output.put_line(‘fixed  ‘||cnt||‘  field(s).’);    
  27. end  pro_fix_varchar;    

  
然后调用这个存储过程:

Sql代码
  

  1. call  pro_fix_varchar();    

  
即可

文章目录
  1. 1. ORACLE 字符集长度问题